package lee.config;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import lee.po.UserPO;
import lee.service.UserService;
import lee.vo.UserVO;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import javax.annotation.Resource;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true, prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    UserService userService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    //密码模式才需要配置,认证管理器
    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/r/r1").hasAnyAuthority("p1")
                .antMatchers("/login*").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin()
        ;
    }

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        return this::loadUserByUsername;
    }

    /**
     * 操作数据库，验证用户名和密码
     */
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        final UserPO userByUsername = userService.findUserByUsername(username);
        final List<UserVO> permission = userService.findPermission(userByUsername.getId());
        if (ObjectUtils.isEmpty(userByUsername)) {
            throw new RuntimeException("此用户不存在");
        }
        Set<String> authorities = permission.stream().map(UserVO::getCode).collect(Collectors.toSet());
        System.err.println(authorities);

        //生成密文  当数据库中是密文的时候  那么不需要转化
//        final String hashpw = BCrypt.hashpw(userByUsername.getPassword(), BCrypt.gensalt());
        return User
                //设置用户名
                .withUsername(userByUsername.getUsername())
                //设置密码222的密文
                .password(userByUsername.getPassword())
                //设置权限
                .authorities(authorities.toArray(new String[0])).build();
    }
}
